import java.awt.*;

import javax.swing.JPanel;
import javax.swing.Timer;
import java.applet.*;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Pacman extends Canvas implements KeyListener, ActionListener {
	
	private Thing map[][];
	
	private int x;
	
	private int y;
	
	private int oldX;
	
	private int oldY;
	
	private short direction = 0;
	
	private boolean b;
	
	private boolean ismoving = false;
	
	private int width;//width of a square with our pacman 
	
	public Pacman(int xP,int yP, Thing map[][]) {
		x = xP;
		y = yP;
		oldX = x;
		oldY = y;
		direction = 0;
		b = false;
		width=30;
		this.map = map;
	}
	
	/**
	 * describes pacman movement 
	 */
	public void move() {
		oldX = x;
		oldY = y;
		if ((direction == 0) && (x != (map[0].length - 1))) {
			if ((map[x + 1][y] == null)||(map[x + 1][y].getClass() != Wall.class))
			x++;
		}
		if ((direction == 1) && (x != 0)) {
			if ((map[x - 1][y] == null) || (map[x - 1][y].getClass() != Wall.class))
			x--;
		}
		if ((direction == 2)  && (y != (map.length - 1))) {
			if ((map[x][y + 1] == null) || (map[x][y + 1].getClass() != Wall.class))
			y++;
		}
		if ((direction == 3)  && (y != 0)) {
			if ((map[x][y - 1] == null) || (map[x][y - 1].getClass() != Wall.class))
			y--;
		}
				
	}
	/**
	 * drawing up
	 * @param g - instance of standart awt class
	 * @param b
	 */
	public void draw_0(Graphics g,final boolean b) {
		if (b == true) {
			//g.setColor(Color.white);
	        //g.fillRect(x * 30, y * 30, 30, 30);
	        g.setColor(Color.yellow);
  		    g.fillArc(x * width,y * width, width, width, 0, 315);
		    g.setColor(Color.black);
		    g.fillArc(x * width + (int)(0.6*width)/*20*/, y * width + (int)(0.16*width)/*5*/, 3, 3, 0, 360);
		} else {
			//g.setColor(Color.white);
			//g.fillRect(x * width + 0, y * width + 0, width, width);
			g.setColor(Color.yellow);
	     	g.fillArc(x * width, y * width, width, width, 0, 360);
			g.setColor(Color.black);
			g.drawArc(x * width + (int)(0.6*width)/*20*/, y * width + (int)(0.16*width), 3, 3, 0, 360);
		}
	}
	
	/**
	 * drawing right
	 * @param g - instance of standart awt class
	 * @param b
	 */
	public void draw_1(Graphics g, final boolean b) {
		if (b == true) {
			//g.setColor(Color.white);
            //g.fillRect(x * width, y * width, width, width);
            g.setColor(Color.yellow);
 		    g.fillArc(x * width, y * width, width, width, 170, - 300);
	        g.setColor(Color.black);
	        g.fillArc(x * width + (int)(0.3*width), y * width + (int)(0.16*width), 3, 3, 0, 360);
		} else {
			//g.setColor(Color.white);
	        //g.fillRect(x * width + 0, y * width + 0, width, width);
	        g.setColor(Color.yellow);
 		    g.fillArc(x * width, y * width, width, width, 0, 360);
	        g.setColor(Color.black);
            g.drawArc(x * width + (int)(0.3*width), y * width + (int)(0.16*width), 3, 3, 0, 360);
		}
	}
	
	/**
	 * drawing down
	 * @param g - instance of standart awt class
	 * @param b
	 */
	public void draw_2(Graphics g, boolean b) {
		if (b == true) {
			//g.setColor(Color.white);
            //g.fillRect(x * width, y * width, width, width);
            g.setColor(Color.yellow);
		    g.fillArc(x * width, y * width, width, width, 245, - 300);
	        g.setColor(Color.black);
	        g.drawArc(x * width + (int)(0.16*width), y * width + (int)(0.6*width), 3, 3, 0, 360);
		} else {
			//g.setColor(Color.white);
	        //g.fillRect(x * width + 0, y * 30 + 0, 30, 30);
	        g.setColor(Color.yellow);
		    g.fillArc(x * width, y * width, width, width, 0, 360);
	        g.setColor(Color.black);
            g.fillArc(x * width + (int)(0.16*width), y * width + (int)(0.6*width), 3, 3, 0, 360);
		}
	}
	
	/**
	 * drawing left
	 * @param g - instance of standart awt class
	 * @param b
	 */
	public void draw_3(Graphics g, boolean b) {
		if (b == true) {
			//g.setColor(Color.white);
            //g.fillRect(x * 30, y * 30, 30, 30);
            g.setColor(Color.yellow);
		    g.fillArc(x * width, y * width, width, width, 50, - 300);
	        g.setColor(Color.black);
	        g.drawArc(x * width + (int)(0.16*width), y * width + (int)(0.3*width), 3, 3, 0, 360);
		} else {
			//g.setColor(Color.white);
	        //g.fillRect(x * 30 + 0, y * 30 + 0, 30, 30);
	        g.setColor(Color.yellow);
		    g.fillArc(x * width, y * width, width, width, 0, 360);
	        g.setColor(Color.black);
            g.fillArc(x * width + (int)(0.16*width), y * width + (int)(0.3*width), 3, 3, 0, 360);
		}
	}
	
	/**
	 * drawing method
	 * @param g - instance of standart awt class
	 */
	public void draw(Graphics g) {
		
		g.setColor(Color.black);
		if (direction == 0)
			draw_0(g, b);
		if (direction == 1)
			draw_1(g, b);
		if (direction == 2)
			draw_2(g, b);
		if (direction == 3)
			draw_3(g, b);
		super.paint(g);
	} 
	
	public void hide(Graphics g) {
		g.setColor(Color.white);
		g.fillRect(oldX * width, oldY * width, width, width);
	}
	
	/**
	 * processing of the pressed key
	 */
    public void keyReleased(KeyEvent arg0) {
        if (KeyEvent.getKeyText(arg0.getKeyCode()).equalsIgnoreCase("w")) {
        	direction = 3;
            ismoving = true;
            oldX = x;
            oldY = y;
        }
        if (KeyEvent.getKeyText(arg0.getKeyCode()).equalsIgnoreCase("s")) {
        	direction = 2;
            ismoving = true;
            oldX = x;
            oldY = y;
        }
        if (KeyEvent.getKeyText(arg0.getKeyCode()).equalsIgnoreCase("a")) {
        	direction = 1;
            ismoving = true;
            oldX = x;
            oldY = y;
        }
        if (KeyEvent.getKeyText(arg0.getKeyCode()).equalsIgnoreCase("d")) {
        	direction = 0;
            ismoving = true;
            oldX = x;
            oldY = y;
        }
    }

    public void keyTyped(KeyEvent e) {
    }
    
    public int getX() {
    	return x;
    }
    
    public int getY() {
    	return y;
    }

    public void keyPressed(KeyEvent e) {
    }
	
	public void actionPerformed(ActionEvent e) {
		b =! b;
		if (ismoving == true)
		{
			move();	
		}
	}
}